﻿using Lab1.DataObjects;
using Lab1.ViewModels;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Reactive.Concurrency;
using System.Reactive.Linq;
using System.Text;
using System.Threading;
using Utils;

namespace Lab1.Controler
{
    internal class MainWindowControler
    {
        public MainWindowViewModel _viewModel { get; set; }

        

        public void OpenFile(object param)
        {
            OpenFileDialog dlg = new OpenFileDialog();

            dlg.DefaultExt = ".txt";
            dlg.Filter = "Text documents (.txt)|*.txt";

            // Display OpenFileDialog by calling ShowDialog method
            Nullable<bool> result = dlg.ShowDialog();

            // Get the selected file name and display in a TextBox
            if (result == true)
            {
                // Open document
                string filename = dlg.FileName;
                var source = new FileStream(dlg.FileName, FileMode.Open, FileAccess.Read);

                var bufferSize = 4096;
                string resultString = String.Empty;
                List<byte> results = new List<byte>();

                List<Document> resultList = new List<Document>();
                source.ToObservable(bufferSize, TaskPoolScheduler.Default)
                    .SubscribeOn(TaskPoolScheduler.Default)
                    .ObserveOn(SynchronizationContext.Current)
                    .Subscribe(
                        bytesRead => 
                        {
                            //resultString = Encoding.Default.GetString(bytesRead);
                            results.Add(bytesRead);
                            //Console.WriteLine("Read {0} bytes from file", bytesRead);
                        },
                        () => 
                        {
                            resultString = Encoding.Default.GetString(results.ToArray());
                            string[] s = resultString.Split(new string[1]{Environment.NewLine}, StringSplitOptions.None);
                            string title = String.Empty;
                            string content = String.Empty;
                            foreach (string line in s)
                            {
                                if (title != String.Empty && line != String.Empty)
                                    content += " " + line;
                                else if (title == String.Empty)
                                    title = line;
                                else if (line == String.Empty)
                                {
                                    resultList.Add(new Document(title, content));
                                    title = String.Empty;
                                    content = String.Empty;
                                }
                            }
                            if (title != String.Empty && content != String.Empty)
                            {
                                resultList.Add(new Document(title, content));
                            }
                            _viewModel.Documents = new ObservableCollection<Document>(resultList); 

                        });
            }
        }

        public void OpenTermsFile(object param)
        {
            OpenFileDialog dlg = new OpenFileDialog();

            dlg.DefaultExt = ".txt";
            dlg.Filter = "Text documents (.txt)|*.txt";

            // Display OpenFileDialog by calling ShowDialog method
            Nullable<bool> result = dlg.ShowDialog();

            // Get the selected file name and display in a TextBox
            if (result == true)
            {
                // Open document
                string filename = dlg.FileName;
                var source = new FileStream(dlg.FileName, FileMode.Open, FileAccess.Read);

                var bufferSize = 4096;
                string resultString = String.Empty;
                List<byte> results = new List<byte>();

                List<Term> resultList = new List<Term>();
                source.ToObservable(bufferSize, TaskPoolScheduler.Default)
                    .SubscribeOn(TaskPoolScheduler.Default)
                    .ObserveOn(SynchronizationContext.Current)
                    .Subscribe(
                        bytesRead =>
                        {
                            //resultString = Encoding.Default.GetString(bytesRead);
                            results.Add(bytesRead);
                            //Console.WriteLine("Read {0} bytes from file", bytesRead);
                        },
                        () =>
                        {
                            resultString = Encoding.Default.GetString(results.ToArray());
                            string[] s = resultString.Split(new string[1] { Environment.NewLine }, StringSplitOptions.None);
                            
                            foreach (string line in s)
                            {
                                resultList.Add(new Term(line));
                            }
                            _viewModel.TermsColl = resultList;

                        });
            }
        }


        public void ProcessQuery(object param)
        {
            if (!String.IsNullOrEmpty(_viewModel.Query))
            {
                TFIDFSol sol = new TFIDFSol
                {
                    db = new List<Document>(_viewModel.Documents.Select<Document, Document>(x => x)),
                    dbKeywords = new List<string>(_viewModel.TermsColl.Select(x => x.KeywordStemmed))
                };
                sol.Process(_viewModel.Query.ToLower());


                if (_viewModel.ExpandQuerry)
                {




                    _viewModel.ExpandQuerryResult =  string.Join(",", _viewModel.eq.findThresures((String)_viewModel.Query.ToLower().Clone()).ToArray());
                    
                }


                _viewModel.DocumentsRanking = new ObservableCollection<Document>(sol.db);
            }
        }

        public void GroupDocuments(object param)
        {
            if (_viewModel.Documents != null)
            {
                TFIDFSol sol = new TFIDFSol
                {
                    db = new List<Document>(_viewModel.Documents.Select<Document, Document>(x => x)),
                    dbKeywords = new List<string>(_viewModel.TermsColl.Select(x => x.KeywordStemmed))
                };
                sol.Group(_viewModel.GroupCount, _viewModel.MaxIteration);

                List<List<Document>> groups = new List<List<Document>>();

                foreach (Group g in sol.groups)
                {
                    var docs = new List<Document>();
                    foreach (int docId in g.DocsAndSimToCentr.Keys)
                    {
                        docs.Add(sol.db.FirstOrDefault(x => x.Id == docId));
                    }
                    groups.Add(docs);
                }

                _viewModel.Groups = new ObservableCollection<List<Document>>(groups);
            }
        }
    }
}
